JAVA实现GBT32960报文解析(三):0x01整车数据解析源码 您所在的位置:网站首页 integer valueof ffffffff 16 JAVA实现GBT32960报文解析(三):0x01整车数据解析源码

JAVA实现GBT32960报文解析(三):0x01整车数据解析源码

#JAVA实现GBT32960报文解析(三):0x01整车数据解析源码| 来源: 网络整理| 查看: 265

**JAVA实现GBT32960报文解析系列文章链接:** JAVA实现GBT32960报文解析(一):掌握协议中的各种数据类型和完整报文结构 JAVA实现GBT32960报文解析(二):数据包结构解析源码 JAVA实现GBT32960报文解析(三):0x01整车数据解析源码 JAVA实现GBT32960报文解析(四):0x02驱动电机数据解析源码 JAVA实现GBT32960报文解析(五):0x03燃料电池数据解析源码(待更…) JAVA实现GBT32960报文解析(六):0x04发动机数据解析源码(待更…) JAVA实现GBT32960报文解析(七):0x05车辆位置数据解析源码(待更…) JAVA实现GBT32960报文解析(八):0x06极值数据解析源码(待更…) JAVA实现GBT32960报文解析(九):0x07报警数据解析源码(待更…) 实战需求示例:车辆月度充电详情统计报表,含快充、慢充区分统计(待更…)

本篇文章目录前言一、车辆状态二、充电状态三、运行模式四、车速五、累计里程六、总电压七、总电流八、SOC九、DC-DC状态十、档位十一、绝缘电阻十二、加速踏板行程值十三、制动踏板状态总结

前言

这是本系列的第三篇文章,从本文开始也就正式进入“数据单元”部分的解析,关于其他部分报文的解析可通过上方系列文章的链接进入了解。

《GB/T 32960.3-2016 电动汽车远程服务与管理系统技术规范 第3部分:通讯协议及数据格式》中,关于数据单元类型为0x01的整车数据格式和定义如下: 在这里插入图片描述

本文将继续对国标报文的剩余部分进行解析,即:0x01 =>【整车数据】部分

提示:下方“删除线”划掉的部分,是从本系列第二篇文章开始已经通过代码示例解析过的报文。

剩余报文信息如下(示例):

232303FE584C32434546355030414C30303730323301012D15071C110B320102030100000000010E0C58271000021013510065020101014F4E204E2055001F271005000633555501D2D2CE0601220D00011F0B1501014B010B49070300000450000000000801010C58271000600001600CBD0CD90CD00CCF0CE00CF00CE00CCB0CE10CE00CDF0CC80CC50CD30CCF0CE70CE50CE30CD90CE90CF60CEF0CE10CDF0CEA0CED0CE80CD10CDA0CEE0B150CD30CED0D000CCA0CED0CD60CDA0CED0CDC0CE70CF00CED0CDF0CF40CF30CDC0CE50CE00CEF0CE10CD20CDD0CE80CD60CEA0CDD0CE90CD90CD60CC90CCB0CDE0CCC0CD30CD60CE60CF20CE20CCC0CE90CE40CF80CA00CE50CE10CE90CE80CE20CF70CF50CEA0CCD0CF80CE50CDD0CE00CE10CE90CDD0CEB0CEE0CF40CF60CFC0CE109010100104B4A4A4A4949494A4A49494A4A4A4A4A5F

一、车辆状态

在这里插入图片描述 关于状态类型的解析:我延续个人的习惯在构造函数中采用Map键值对的方式定义,使其在初始化时就存储定义好,等到解析调用时通过Map.get()方法去取出对应的value值。

车辆状态解析,代码如下(示例):

// 构造函数中定义车辆状态vehicleStateMap = new HashMap();vehicleStateMap.put("0x01", "车辆启动状态");vehicleStateMap.put("0x02", "熄火");vehicleStateMap.put("0x03", "其他状态");vehicleStateMap.put("0xFE", "异常");vehicleStateMap.put("0xFF", "无效"); // 解析调用(下标0是数据单元类型的定义,在主方法中已经处理,所以这里从下标1开始)map.put("车辆状态", vehicleStateMap.get("0x" + bytes[1])); 二、充电状态

在这里插入图片描述

充电状态解析,代码如下(示例):

// 构造函数中定义充电状态chargeModeMap = new HashMap();chargeModeMap.put("0x01", "停车充电");chargeModeMap.put("0x02", "行驶充电");chargeModeMap.put("0x03", "未充电");chargeModeMap.put("0x04", "充电完成");chargeModeMap.put("0xFE", "异常");chargeModeMap.put("0xFF", "无效"); // 解析调用map.put("充电状态", chargeModeMap.get("0x" + bytes[2])); 三、运行模式

在这里插入图片描述

运行模式解析,代码如下(示例):

// 构造函数中定义运行模式runStateMap = new HashMap();runStateMap.put("0x01", "纯电");runStateMap.put("0x02", "混动");runStateMap.put("0x03", "燃油");runStateMap.put("0xFE", "异常");runStateMap.put("0xFF", "无效"); // 解析调用map.put("运行模式", runStateMap.get("0x" + bytes[3])); 四、车速

在这里插入图片描述 关于数值类型的解析:需要优先处理异常和无效数据的,然后注意是否有最小计量单位和偏移量的描述。这些都需要一一处理,否则数据值解析错误很难直观看出。

车速解析,代码如下(示例):

/*** 车速* @param strByte* @return*/private String byte2speed(String strByte){if(strByte.equals("FFFE")){return "异常";}else if(strByte.equals("FFFF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));// 精确到0.1km,所以在这里除以10BdByte = BdByte.divide(new BigDecimal(10));return BdByte.toString();} 五、累计里程

在这里插入图片描述

累计里程解析,代码如下(示例):

/*** 累计里程* @param strByte* @return*/private String byte2odometer(String strByte){if(strByte.equals("FFFFFFFE")){return "异常";}else if(strByte.equals("FFFFFFFF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));// 精确到0.1km,所以在这里除以10BdByte = BdByte.divide(new BigDecimal(10));return BdByte.toString();} 六、总电压

在这里插入图片描述

总电压解析,代码如下(示例):

/*** 总电压* @param strByte* @return*/private String byte2totalVoltage(String strByte){if(strByte.equals("FFFE")){return "异常";}else if(strByte.equals("FFFF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));// 精确到0.1V,所以在这里除以10BdByte = BdByte.divide(new BigDecimal(10));return BdByte.toString();} 七、总电流

在这里插入图片描述

总电流解析,代码如下(示例):

/*** 总电流* @param strByte* @return*/private String byte2totalCurrent(String strByte){if(strByte.equals("FFFE")){return "异常";}else if(strByte.equals("FFFF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));// 精确到0.1A,所以在这里除以10BdByte = BdByte.divide(new BigDecimal(10));// 偏移量1000A,有效范围值:-1000A~1000ABdByte = BdByte.subtract(new BigDecimal(1000));return BdByte.toString();} 八、SOC

在这里插入图片描述

SOC解析,代码如下(示例):

/*** SOC* @param strByte* @return*/private String byte2soc(String strByte){if(strByte.equals("FE")){return "异常";}else if(strByte.equals("FF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));return BdByte.toString();} 九、DC-DC状态

在这里插入图片描述

DC-DC状态解析,代码如下(示例):

// 构造函数中定义DC-DC状态dc_dcStateMap = new HashMap();dc_dcStateMap.put("0x01", "工作");dc_dcStateMap.put("0x02", "断开");dc_dcStateMap.put("0xFE", "异常");dc_dcStateMap.put("0xFF", "无效"); // 解析调用map.put("DC-DC状态", dc_dcStateMap.get("0x" + bytes[15])); 十、档位

在这里插入图片描述 档位的报文信息,其实包含三个部分(抛出前面的两个预留字符过后):驱动状态、制动状态、档位。这里仅为了阅读便捷不在构建函数中单独做map定义,整体放在一个方法中去编写。

档位解析,代码如下(示例):

/*** 档位* @param strByte* @return*/private String byte2gearshift(String strByte){String str = null;strByte = ParseUtils.hexStr2Byte(strByte);// 驱动状态解析if(strByte.substring(2, 3).equals("1"))str = "有驱动力";elsestr = "无驱动力";// 制动状态解析 if(strByte.substring(3, 4).equals("1"))str += ",有制动力";elsestr += ",无制动力";// 档位解析 switch (strByte.substring(4, 8)) {case "0000":str += ",空挡";break;case "0001":str += ",1挡";break;case "0010":str += ",2挡";break;case "0011":str += ",3挡";break;case "0100":str += ",4挡";break;case "0101":str += ",5挡";break;case "0110":str += ",6挡";break;case "1101":str += ",倒挡";break;case "1110":str += ",自动D挡";break;case "1111":str += ",停车P挡";break;default:System.out.println("not match !!!");}return str;}

提示:ParseUtils类是在第一篇文章中实现的代码类

十一、绝缘电阻

在这里插入图片描述

绝缘电阻解析,代码如下(示例):

// 绝缘电阻map.put("绝缘电阻", Integer.valueOf(bytes[17] + bytes[18], 16).toString()); 十二、加速踏板行程值

在这里插入图片描述

加速踏板行程值解析,代码如下(示例):

/*** 加速踏板行程值* @param strByte* @return*/private String byte2accPedalVal(String strByte){if(strByte.equals("FE")){return "异常";}else if(strByte.equals("FF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));return BdByte.toString();} 十三、制动踏板状态

在这里插入图片描述

制动踏板状态解析,代码如下(示例):

/*** 制动踏板状态* @param strByte* @return*/private String byte2brakePedalState(String strByte){if(strByte.equals("65")){return "有效,但暂无具体值";}else if(strByte.equals("FE")){return "异常";}else if(strByte.equals("FF")){return "无效";}// 排除以上两种情况后,就可以直接当做数字处理BigDecimal BdByte = new BigDecimal(Integer.valueOf(strByte, 16));return BdByte.toString();} 总结

根据文章结尾可下载的完整代码示例,最终通过System.out.println("CompleteVehicle Map => " + map);打印到控制台。

控制台输出结果如下:

CompleteVehicle Map => {运行模式=纯电, 总电压=316, SOC=0, 档位=无驱动力,有制动力,空挡, 车速=0, 充电状态=未充电, 总电流=0, 车辆状态=熄火, 绝缘电阻=4945, 累计里程=27, 制动踏板状态=有效,但暂无具体值, 加速踏板行程值=0, DC-DC状态=断开}

从下一篇文章,继续解析:数据单元信息标识为0x02的驱动电机数据源码

** 相关下载:** 国标协议GBT32960文档 (包含《GB/T 32960-2016 电动汽车远程服务与管理系统技术规范》完整的1、2、3部分) 源码部分: JAVA解析GBT32960协议 - 数据包结构源码(另含ParseUtils.java和BCCVerifyUtils.java两个工具类) JAVA解析GBT32960协议 - 0x01整车数据源码 JAVA解析GBT32960协议 - 0x02驱动电机数据源码 JAVA解析GBT32960协议 - 0x03燃料电池数据源码(待更…) JAVA解析GBT32960协议 - 0x04发动机数据源码(待更…) JAVA解析GBT32960协议 - 0x05车辆位置数据源码(待更…) JAVA解析GBT32960协议 - 0x06极值数据源码(待更…) JAVA解析GBT32960协议 - 0x07报警数据源码(待更…)



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有